home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / UTILITY1 / MSWSRC35.ZIP / PRINTER.CPP < prev    next >
C/C++ Source or Header  |  1993-10-12  |  23KB  |  817 lines

  1.  
  2. // ObjectWindows - (C) Copyright 1992 by Borland International
  3.  
  4. //#include <windows.h>
  5. //#include <owl.h>
  6. //#include "printer.h"
  7. //#include "logorc.h"
  8.  
  9. #include "allwind.h"
  10.  
  11. #include "mycombo.h"
  12. #include <static.h>
  13. #include <safepool.h>
  14.  
  15. // A few private constants
  16.  
  17. #define SR_ON 32512
  18. #define SR_ERRORTEMPLATE 32513
  19. #define SR_OUTOFMEMORY 32514
  20. #define SR_OUTOFDISK 32515
  21. #define SR_PRNCANCEL 32516
  22. #define SR_PRNMGRABORT 32517
  23. #define SR_GENERROR 32518
  24. #define SR_ERRORCAPTION 32519
  25.  
  26. static BOOL UserAbort = FALSE;
  27.  
  28.  
  29. /*
  30. ** FetchStr
  31. ** Returns a pointer to the first comma delimited field pointed to
  32. ** by Str. It replaces the comma with a a null character and moves the Str
  33. ** to the beginning of the next string (skipping white space). Str will
  34. ** will point to a null character if no more strings are left. This
  35. ** routine is used to fetch strings out of text retrieved from WIN.INI.
  36. */
  37.  
  38. static Pchar FetchStr(Pchar& Str)
  39.    {
  40.    Pchar result = Str;
  41.    LPSTR tempStr = Str;  // Used because AnsiNext returns an LPSTR;
  42.    // Note that we could simply use Str instead
  43.    // if we assumed a large data model.
  44.    
  45.    if (Str == NULL)
  46.    return result;
  47.    while ((*tempStr != '\0') && (*tempStr != ','))
  48.    tempStr = AnsiNext(tempStr);
  49.    if (*tempStr != '\0')
  50.       {
  51.       *tempStr = '\0';
  52.       tempStr++;
  53.       while (*tempStr == ' ')
  54.       tempStr = AnsiNext(tempStr);
  55.       }
  56.    // Change Str to point to next field.
  57.    Str += int(tempStr - (LPSTR) Str);
  58.    return result;
  59.    }
  60.  
  61.  
  62. /*
  63. ** newstrdup
  64. ** Allocate space for and copy a string; allocation is performed
  65. ** using 'new' so 'delete' should be used for de-allocation.
  66. */
  67.  
  68. static Pchar newstrdup(Pchar S)
  69.    {
  70.    Pchar P = new char[strlen(S)+1];
  71.    strcpy(P, S);
  72.    return P;
  73.    }
  74.  
  75.  
  76. // TPrintout
  77.  
  78.  
  79. TPrintout::TPrintout(Pchar ATitle)
  80.    {
  81.    Title = newstrdup(ATitle);
  82.    Banding = FALSE;
  83.    ForceAllBands = TRUE;
  84.    }
  85.  
  86. TPrintout::~TPrintout()
  87.    {
  88.    delete Title;
  89.    }
  90.  
  91. BOOL TPrintout::IsNextPage()
  92.    {
  93.    return FALSE;
  94.    }
  95.  
  96. // TReplaceStatic
  97.  
  98. _CLASSDEF(TReplaceStatic)
  99. class TReplaceStatic: public TStatic
  100.    {
  101.    private:
  102.    Pchar Text;
  103.    public:
  104.    TReplaceStatic(PTWindowsObject AParent, int ResourceId, Pchar AText);
  105.    virtual ~TReplaceStatic();
  106.    virtual void SetupWindow();
  107.    };
  108.  
  109. TReplaceStatic::TReplaceStatic(PTWindowsObject AParent, int ResourceId,
  110. Pchar AText) : TStatic(AParent, ResourceId, 0)
  111.    {
  112.    Text = newstrdup(AText);
  113.    }
  114.  
  115. TReplaceStatic::~TReplaceStatic()
  116.    {
  117.    delete Text;
  118.    }
  119.  
  120. void TReplaceStatic::SetupWindow()
  121.    {
  122.    char A[80];
  123.    char B[80];
  124.    
  125.    TStatic::SetupWindow();
  126.    GetText(A, sizeof(A) - 1);
  127.    LPSTR C[1];
  128.    C[0] = Text;
  129.    wvsprintf((LPSTR) B, (LPSTR) A, (LPSTR) C);
  130.    SetText(B);
  131.    }
  132.  
  133.  
  134. // TPrinterAbortDlg
  135.  
  136. TPrinterAbortDlg::TPrinterAbortDlg(PTWindowsObject AParent, Pchar Template,
  137. Pchar Title, Pchar Device, Pchar Port)
  138. : TDialog(AParent, Template)
  139.    {
  140.    new TReplaceStatic(this, ID_TITLE, Title);
  141.    new TReplaceStatic(this, ID_DEVICE, Device);
  142.    new TReplaceStatic(this, ID_PORT, Port);
  143.    }
  144.  
  145. void TPrinterAbortDlg::SetupWindow()
  146.    {
  147.    TDialog::SetupWindow();
  148.    EnableMenuItem(GetSystemMenu(HWindow, FALSE), SC_CLOSE, MF_GRAYED);
  149.    }
  150.  
  151. void TPrinterAbortDlg::WMCommand(RTMessage)
  152.    {
  153.    UserAbort = TRUE;
  154.    }
  155.  
  156.  
  157. // TPrinter
  158.  
  159. /*
  160. **  This object type is an encapsulation around the Windows printer
  161. **  device interface.  After the object is initialized the Status
  162. **  field must be checked to see if the object was created correctly.
  163. **
  164. **  Examples:
  165. **   Creating a default device printing object:
  166. **
  167. **     DefaultPrinter = new TPrinter();
  168. **
  169. **   Creating a device for a specific printer:
  170. **
  171. **     PostScriptPrinter = new TPrinter();
  172. **     PostScriptPrinter->SetDevice("PostScript Printer",
  173. **       "PSCRIPT", "LPT2:");
  174. **
  175. **   Allowing the user to configure the printer:
  176. **
  177. **     DefaultPrinter->Configure(MyWindow);
  178. */
  179.  
  180. // Initialize the TPrinter object assigned to the default printer
  181.  
  182. TPrinter::TPrinter()
  183.    {
  184.    Device = NULL;
  185.    Driver = NULL;
  186.    Port = NULL;
  187.    DeviceModule = 0;
  188.    DevSettings = NULL;
  189.    Error = 0;
  190.    SetDevice(NULL, NULL, NULL);  // Associate with default printer
  191.    }
  192.  
  193. // Deallocate allocated resources
  194.  
  195. TPrinter::~TPrinter()
  196.    {
  197.    ClearDevice();
  198.    }
  199.  
  200. // Clears the association of this object with the current device
  201.  
  202. void TPrinter::ClearDevice()
  203.    {
  204.    if (Device) delete Device;
  205.    Device = NULL;
  206.    
  207.    if (Driver) delete Driver;
  208.    Driver = NULL;
  209.    
  210.    if (Port) delete Port;
  211.    Port = NULL;
  212.    
  213.       if ((int)DeviceModule >= 32) {
  214.       FreeLibrary(DeviceModule);
  215.       DeviceModule = 0;
  216.       }
  217.    if (DevSettings)
  218.    delete [] (Pchar) DevSettings;
  219.    Status = PS_UNASSOCIATED;
  220.    }
  221.  
  222.  
  223. // GetDefaultPrinter and Equal are helper functions used by
  224. // TPrinter::SetDevice
  225.  
  226. void TPrinter::GetDefaultPrinter()
  227.    {
  228.    char Printer[80];
  229.    Pchar Cur;
  230.    
  231.    GetProfileString("windows", "device", "", Printer,
  232.    sizeof(Printer) - 1);
  233.    Cur = Printer;
  234.    Device = newstrdup(FetchStr(Cur));
  235.    Driver = newstrdup(FetchStr(Cur));
  236.    Port = newstrdup(FetchStr(Cur));
  237.    }
  238.  
  239. static BOOL Equal(Pchar S1, Pchar S2)
  240.    {
  241.    return ((S1 != NULL) && (S2 != NULL) && (strcmp(S1, S2) == 0));
  242.    }
  243.  
  244. /*
  245. Associates the printer object with a new device. If the ADevice
  246. parameter is NULL the Windows default printer is used, otherwise,
  247. the parameters must be ones contained in the [devices] section
  248. of the WIN.INI file.
  249. */
  250.  
  251. void TPrinter::SetDevice(Pchar ADevice, Pchar ADriver, Pchar APort)
  252.    {
  253.    char DriverName[80];
  254.    DEVMODE StubDevMode;
  255.    
  256.    if (Equal(Device, ADevice) && Equal(Driver, ADriver) &&
  257.    Equal(Port, APort))
  258.    return;
  259.    ClearDevice();
  260.    if (ADevice == NULL)
  261.    GetDefaultPrinter();
  262.       else {
  263.       Device = newstrdup(ADevice);
  264.       Driver = newstrdup(ADriver);
  265.       Port = newstrdup(APort);
  266.       }
  267.    Status = PS_OK;
  268.    strncpy(DriverName, Driver, sizeof(DriverName) - 1);
  269.    strncat(DriverName, ".DRV", sizeof(DriverName) - strlen(DriverName) - 1);
  270.    DeviceModule = LoadLibrary(DriverName);
  271.    if ((int)DeviceModule < 32)
  272.    Status = PS_INVALIDDEVICE;
  273.       else {
  274.       // Grab the DevMode procedures
  275.       ExtDeviceMode = (LPFNDEVMODE) GetProcAddress(DeviceModule, "ExtDeviceMode");
  276.       DeviceMode = (PTDeviceModeFcn) GetProcAddress(DeviceModule, "DeviceMode");
  277.       if ((DeviceMode == NULL) && (ExtDeviceMode == NULL))
  278.       Status = PS_INVALIDDEVICE;
  279.          if (ExtDeviceMode != NULL) {
  280.          // Get default printer settings
  281.          DevSettingSize = ExtDeviceMode(0, DeviceModule, &StubDevMode,
  282.          Device, Port, &StubDevMode, NULL, 0);
  283.          DevSettings = (PDEVMODE) new char[DevSettingSize];
  284.          ExtDeviceMode(0, DeviceModule, DevSettings, Device, Port,
  285.          DevSettings, NULL, DM_OUT_BUFFER);
  286.          }
  287.       else
  288.       DevSettings = NULL;  // Cannot use local settings
  289.       }
  290.    }
  291.  
  292. // Configure brings up a dialog as a child of the given window
  293. // to configure the associated printer driver.
  294.  
  295. void TPrinter::Configure(PTWindowsObject Window)
  296.    {
  297.    if (Status == PS_OK)
  298.    if (ExtDeviceMode == NULL) // driver only supports DevMode
  299.    // if DeviceMode == NULL, Status will != PS_OK
  300.    DeviceMode(Window->HWindow, DeviceModule, Device, Port);
  301.    else
  302.    // Request driver to modify local copy of printer settings
  303.    ExtDeviceMode(Window->HWindow, DeviceModule, DevSettings, Device,
  304.    Port, DevSettings, NULL, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER);
  305.    }
  306.  
  307. // Returns a device context for the associated printer, 0 if an
  308. // error occurs or Status is != PS_OK
  309.  
  310. HDC TPrinter::GetDC()
  311.    {
  312.    if (Status == PS_OK)
  313.    return CreateDC(Driver, Device, Port, (LPSTR) (LPDEVMODE) DevSettings);
  314.    else
  315.    return 0;
  316.    }
  317.  
  318. static BOOL ProcessDlgMsg(LPMSG PMessage, PTApplication Application)
  319.    {
  320.    if (Application->KBHandlerWnd && Application->KBHandlerWnd->HWindow)
  321.    return IsDialogMessage(Application->KBHandlerWnd->HWindow, PMessage);
  322.    else
  323.    retur